﻿using Client;
using Communication.Shared;
using ManageSystem.Dialog;
using Newtonsoft.Json;
using Seagull.BarTender.Print;
using Shared.Method;
using Shared.Model;
using Shared.SoftMethod;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using SharedClientDll;
using System.Text;

namespace MacXponSnBinding
{
    public partial class FormPacking : Form
    {
        private readonly string DATA_DIR_ONE = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "DATA\\";//保存包装数据
        private readonly string DATA_DIR_TWO = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "DATA_TWO\\";//保存包装数据
        private readonly string DATA_DIR_PACK = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "DATA_PACK\\";//保存包装数据

        //private string  _packSet.PACKING_END_SN;
        private readonly string DB_PATH = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "Database\\";
        private readonly string DB_FILE = "localpacking.db";
        private readonly string EXCEL_PATH = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + $"Excel\\{ DateTime.Now.ToString("yyyyMMdd") } \\";

        private SQLiteConnection _sqliteConn;

        //private List<Device_Type> _listDeviceType = null;//保存产品类型信息
        private Device_Type _deviceType = null;

        private readonly object s_lockObj = new object();

        public FormPacking()
        {
            InitializeComponent();
        }

        //滚动窗体
        private void RichTextBoxMsg_TextChanged(object sender, EventArgs e)
        {
            this.richTextBoxMsg.SelectionStart = this.richTextBoxMsg.Text.Length;
            this.richTextBoxMsg.ScrollToCaret();
        }

        //将信息写入RichTextBox
        private void AppendRichTextBox(string value)
        {
            if (this.richTextBoxMsg.InvokeRequired)
            {
                Action<string> d = new Action<string>(AppendRichTextBox);
                Invoke(d, new object[] { value });
            }
            else
            {
                if (value == null) return;
                if (this.richTextBoxMsg.TextLength >= 10000)
                    this.richTextBoxMsg.Clear();
                this.richTextBoxMsg.AppendText(value);
                this.richTextBoxMsg.AppendText("\n");
            }
        }

        //private YCD_ORDER _order = null;//保存ORDER信息
        private string _fileName, _fileNameTwo, _fileNamePack;

        //private List<string> _listBoxNo = new List<string>();//保存当前扫描箱号
        private int _inputBoxNumber = 0;
        private readonly List<string> _totalBoxNo = new List<string>();//保存所有箱号

        //private string _keyWord = Guid.NewGuid().ToString();//每一个栈板的唯一GUID值

        #region 使用SQLite方案打包

        private PackingMessage _packSet = new PackingMessage();
        private Queue<string> _queueBoxNo = new Queue<string>();
        private bool _packGroup = false;
        /// <summary>
        ///传入箱号，并处理
        /// </summary>
        private bool PackingBoxNo(string boxNo)
        {
            if (string.IsNullOrEmpty(boxNo) || boxNo.Length != 18)
            {
                AppendRichTextBox($"箱号错误：[{boxNo}]");
                return false;
            }

            //解析箱号
            BOX_MODEM boxW = new BOX_MODEM();
            boxW.SetWhere();
            boxW.BOX_NO = boxNo;

            var selectBox = MethodWcf.SelectBoxModemClient(boxW);
            if (selectBox.result == false)
            {
                AppendRichTextBox($"未能找到箱号数据[{boxNo}]");
                return false;
            }

            BOX_MODEM boxModem = selectBox.value[0];

            string identify = " IN('";

            for (int j = 1; j <= boxModem.COUNT; j++)
            {
                switch (j)
                {
                    case 1:
                        identify += boxModem.DSNum_1 + "','";
                        break;
                    case 2:
                        identify += boxModem.DSNum_2 + "','";
                        break;
                    case 3:
                        identify += boxModem.DSNum_3 + "','";
                        break;
                    case 4:
                        identify += boxModem.DSNum_4 + "','";
                        break;
                    case 5:
                        identify += boxModem.DSNum_5 + "','";
                        break;
                    case 6:
                        identify += boxModem.DSNum_6 + "','";
                        break;
                    case 7:
                        identify += boxModem.DSNum_7 + "','";
                        break;
                    case 8:
                        identify += boxModem.DSNum_8 + "','";
                        break;
                    case 9:
                        identify += boxModem.DSNum_9 + "','";
                        break;
                    case 10:
                        identify += boxModem.DSNum_10 + "','";
                        break;
                    case 11:
                        identify += boxModem.DSNum_11 + "','";
                        break;
                    case 12:
                        identify += boxModem.DSNum_12 + "','";
                        break;
                    case 13:
                        identify += boxModem.DSNum_13 + "','";
                        break;
                    case 14:
                        identify += boxModem.DSNum_14 + "','";
                        break;
                    case 15:
                        identify += boxModem.DSNum_15 + "','";
                        break;
                    case 16:
                        identify += boxModem.DSNum_16 + "','";
                        break;
                    case 17:
                        identify += boxModem.DSNum_17 + "','";
                        break;
                    case 18:
                        identify += boxModem.DSNum_18 + "','";
                        break;
                    case 19:
                        identify += boxModem.DSNum_19 + "','";
                        break;
                    case 20:
                        identify += boxModem.DSNum_20 + "','";
                        break;
                    default:
                        break;
                }
            }

            identify = identify.TrimEnd(',', '\'') + "')";

            //判断identify是否在本地
            string checkInSQL = $"SELECT * FROM LOCAL_PACKING WHERE DEVICE_SERIAL_NUMBER {identify} ORDER BY SN";
            List<LOCAL_PACKING> listCheck = SQLiteMethod.ExecReader<LOCAL_PACKING>(_sqliteConn, checkInSQL);

            if (listCheck != null && listCheck.Count > 0)
            {
                for (int j = 0; j < listCheck.Count; j++)
                {
                    var packing = listCheck[j];
                    AppendRichTextBox(string.Format("LOCAL:MAC[{0}]已经出货，不能再次扫描，SN[{1}]，BOX_SN[{2}],发货时间[{3}]，栈板编码{4}]", packing.MAC, packing.SN, packing.BOX_NO, packing.PACKING_TIME, packing.PACKING_NUM));
                }
                return false;
            }

            //查询IDENTIFY是否在包装数据当中
            PACKING packW = new PACKING();
            packW.SetWhere(string.Format("IDENTIFY {0} ORDER BY ID", identify));
            var selectPacking = MethodWcf.SelectPackingClient(packW);
            if (selectPacking.result)
            {
                for (int j = 0; j < selectPacking.value.Count; j++)
                {
                    var packing = selectPacking.value[j];
                    AppendRichTextBox(string.Format("SERVER:MAC[{0}]已经出货，不能再次扫描，SN[{1}]，BOX_SN[{2}],发货时间[{3}]，栈板编码{4}]", packing.MAC, packing.SN, packing.BOX_NO, packing.PACKING_TIME.ToString("yyyyMMdd"), packing.PACKING_NUM));
                }

                MessageBox.Show("产品已经出货，不能再次扫描");

                //_inputBoxNumber = 0;
                return false;
            }

#if true
            //查询identify对应的数据
            Device_Data deviceDataW = new Device_Data();
            deviceDataW.SetWhere(string.Format("DeviceSerialNumber {0} ORDER BY SN", identify));

            var selectDeviceData = MethodWcf.SelectDeviceDataClient(deviceDataW);
            if (selectDeviceData.result == false)
            {
                MessageBox.Show("查询产品信息错误");
                AppendRichTextBox("查询产品信息错误");
                return false;
            }

            List<Device_Data> listValue = selectDeviceData.value;
#else
            //user view device data
            string sqlSelectDevice = $"SELECT * FROM Modem.dbo.Device_Data WHERE DeviceSerialNumber {identify} ORDER BY SN";
            var listDevice = MethodWcf.SelectJsonClient<List<Device_Data>>(sqlSelectDevice);

            if (listDevice == null || listDevice.Count == 0)
            {
                AppendRichTextBox("查询产品数据失败");
                return false;
            }


            List<Device_Data> listValue = listDevice;
#endif

            List<LOCAL_PACKING> listLocalPack = new List<LOCAL_PACKING>();

            //将数据存入SQLite中
            for (int i = 0; i < listValue.Count; i++)
            {
                LOCAL_PACKING pack = new LOCAL_PACKING()
                {
                    DEVICE_TYPE = _deviceType.DeviceType,
                    PRODUCT_CODE=listValue[i].ProductCode,
                    HW_PROVINCE_NAME = _deviceType.PROVINCE,
                    MAC = listValue[i].MACAddr,
                    SN = listValue[i].SN,
                    BOX_NO = boxNo,
                    XPON_SN = listValue[i].XPON_SN,
                    SSID = listValue[i].WIFI_SSID,
                    SSID_PWD = listValue[i].WIFI_Password,
                    MODEM_IP=listValue[i].LanIP,
                    WEB_USER = listValue[i].WedUser,
                    WEB_PWD = listValue[i].WedPassword,
                    DEVICE_SERIAL_NUMBER = listValue[i].DeviceSerialNumber,
                    FACTORY_CODE = "YHTC",
                    HW_VERSION = _deviceType.HWVersion,
                    SW_VERSION = _deviceType.SWVersionInside,
                    BUILD_TIME = listValue[i].BUILD_TIME,
                    SYSTEM = "linux",
                    SYSTEM_VERSION = "2.6.36",
                    PRODUCTION_TIME = listValue[i].date1.ToString("yyyyMMdd"),
                    //SEND_TIME=DateTime.Now.ToString("yyyyMMdd"),
                    ONT_TYPE = "IHGU",
                    FACTORY_NAME = "友华",
                    BRANCH_NAME = string.Empty,
                    CONTEXT = "G-140W-C  GPON光终端(1个POTS,4个GE接口,交流供电)",
                    KEY = _packSet.KEY,
                    PACKING_TIME = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"),
                    PACKING_NUM = $"{_packSet.TOTAL_GROUP}_{_packSet.SORT_GROUP}"
                };

                listLocalPack.Add(pack);
            }

            DataTable table = JsonConvert.DeserializeObject<DataTable>(JsonConvert.SerializeObject(listLocalPack));

            SQLiteMethod.ReplaceFromDataTable(_sqliteConn, table, "LOCAL_PACKING");


            return true;
        }

        private void PackingThree()
        {
            //从SQLite中获取数据
            string selectSQL = $"SELECT * FROM LOCAL_PACKING WHERE KEY='{_packSet.KEY}' ORDER BY SN";
            List<LOCAL_PACKING> listLocal = SQLiteMethod.ExecReader<LOCAL_PACKING>(_sqliteConn, selectSQL);

            if (listLocal == null || listLocal.Count == 0)
            {
                AppendRichTextBox("打包栈板失败，从本地获取数据失败");
                return;
            }

            //写本地数据
            string updateSQL = "UPDATE LOCAL_PACKING SET KEY='PASS' WHERE MAC IN({0})";
            string macList = string.Empty;

            //保存打包SN数据
            List<PRODUCT_SN> listProSn = new List<PRODUCT_SN>();

            StringBuilder sqlBuf = new StringBuilder();
            sqlBuf.AppendLine(SharedData.SQL_TRANSCATION_START);

            PACKING packI = new PACKING();
            for (int i = 0; i < listLocal.Count; i++)
            {
                packI.Clear();
                packI.SetUpdate();

                packI.MAC = listLocal[i].MAC;
                packI.IDENTIFY = listLocal[i].DEVICE_SERIAL_NUMBER;
                packI.SN = listLocal[i].SN;
                packI.BOX_NO = listLocal[i].BOX_NO;
                packI.PROVINCE = listLocal[i].HW_PROVINCE_NAME;
                packI.DEVICE_TYPE = listLocal[i].DEVICE_TYPE;
                packI.PACKING_NUM = listLocal[i].PACKING_NUM;
                packI.BATCH = $"{DateTime.Now.ToString("yyyyMMdd")}{_deviceType.PROVINCE}_{_deviceType.DeviceType}";
                packI.PACKING_TIME = DateTime.Parse(listLocal[i].PACKING_TIME);

                sqlBuf.AppendLine(ObjectToSQL.ObjectToInsertSql(packI));

                macList += $"'{listLocal[i].MAC}',";

                //获得打包SN数据
                if (int.TryParse(listLocal[i].SN.Substring(12), out int snNum) == false)
                {
                    AppendRichTextBox(string.Format("截取sn失败,MAC[{0}],SN[{1}]", listLocal[i].MAC, listLocal[i].SN));
                    //return;
                }

                PRODUCT_SN sn = new PRODUCT_SN() { SN_NUM = snNum, FULL_PRODUCT_SN = listLocal[i].SN };

                listProSn.Add(sn);

                continue;

                var insert = MethodWcf.InsertPackingClient(packI);
                if (insert.result)
                {
                    AppendRichTextBox($"写入成功，MAC：{listLocal[i].MAC}，SN：{listLocal[i].SN}，BOX_NO：{listLocal[i].BOX_NO}");
                    macList += $"'{listLocal[i].MAC}',";
                }
                else
                {
                    AppendRichTextBox($"写入失败，MAC：{listLocal[i].MAC}，SN：{listLocal[i].SN}，BOX_NO：{listLocal[i].BOX_NO}");
                }
            }

            sqlBuf.AppendLine(SharedData.SQL_TRANSCATION_END);
            int executeNumber = MethodWcf.ExecuteSQLClient(sqlBuf.ToString());

            if (executeNumber <= 0)
            {
                AppendRichTextBox("更新数据失败,不能打包栈板");
                return;
            }

            AppendRichTextBox($"更新数据量为：{executeNumber}");

            //更新本地存储库
            int execRows = SQLiteMethod.ExecSQL(_sqliteConn, string.Format(updateSQL, macList.TrimEnd(',')));
            AppendRichTextBox($"更新本地数据库成功\r\n更新数量：{execRows}");


            if (listProSn[listProSn.Count - 1].SN_NUM - listProSn[0].SN_NUM == listProSn.Count - 1)
            {
                SetControl(labelStartSn, listProSn[0].FULL_PRODUCT_SN);
                SetControl(labelEndSn, listProSn[listProSn.Count - 1].FULL_PRODUCT_SN);

                int packingNum = listProSn.Count;

                LabelPrint(_packSet.SORT_GROUP, _packSet.TOTAL_GROUP, packingNum, listProSn[0].FULL_PRODUCT_SN, listProSn[listProSn.Count - 1].FULL_PRODUCT_SN, _packSet.PACKING_BTW_PATH);
            }
            else
            {
                var list = SplitSnTwo(listProSn);

                for (int i = 0; i < list.Count; i++)
                {
                    SetControl(this.labelStartSn, list[i].StartSn);
                    SetControl(this.labelEndSn, list[i].EndSn);

                    //计算打包数量
                    int packingNum = int.Parse(list[i].EndSn.Substring(12)) - int.Parse(list[i].StartSn.Substring(12)) + 1;

                    LabelPrint(_packSet.SORT_GROUP, _packSet.TOTAL_GROUP, packingNum, list[i].StartSn, list[i].EndSn, _packSet.PACKING_BTW_PATH);
                }
            }

            _packSet.SORT_GROUP++;
            SetControl(textBoxGorupSort, _packSet.SORT_GROUP.ToString());
            AppendRichTextBox("打印标签完成");

            //return true;
        }

        private void ExportData()
        {
            //从本地数据库中导出数据
            //查询数据是否有非PASS的
            string selectSQL = "SELECT * FROM LOCAL_PACKING ORDER BY DEVICE_TYPE,HW_PROVINCE_NAME";
            List<LOCAL_PACKING> packs = SQLiteMethod.ExecReader<LOCAL_PACKING>(_sqliteConn, selectSQL);

            if (packs == null || packs.Count == 0)
            {
                AppendRichTextBox("本地无数据，不需要导出");
                return;
            }

            List<LOCAL_PACKING> leftPack = packs.Where(a => a.KEY != "PASS").ToList();

            if (leftPack != null && leftPack.Count > 0)
            {
                //写本地数据
                string updateSQL = "UPDATE LOCAL_PACKING SET KEY='PASS' WHERE MAC IN({0})";
                string macList = string.Empty;

                bool success = true;

                PACKING packI = new PACKING();
                for (int i = 0; i < leftPack.Count; i++)
                {
                    packI.Clear();
                    packI.SetUpdate();

                    packI.MAC = leftPack[i].MAC;
                    packI.IDENTIFY = leftPack[i].DEVICE_SERIAL_NUMBER;
                    packI.SN = leftPack[i].SN;
                    packI.BOX_NO = leftPack[i].BOX_NO;
                    packI.PROVINCE = leftPack[i].HW_PROVINCE_NAME;
                    packI.DEVICE_TYPE = leftPack[i].DEVICE_TYPE;
                    packI.PACKING_NUM = leftPack[i].PACKING_NUM;
                    packI.BATCH = $"{DateTime.Now.ToString("yyyyMMdd")}{leftPack[i].HW_PROVINCE_NAME}_{leftPack[i].DEVICE_TYPE}";
                    packI.PACKING_TIME = DateTime.Parse(leftPack[i].PACKING_TIME);

                    var insert = MethodWcf.InsertPackingClient(packI);
                    if (insert.result)
                    {
                        AppendRichTextBox($"写入成功，MAC：{leftPack[i].MAC}，SN：{leftPack[i].SN}，BOX_NO：{leftPack[i].BOX_NO}"); ;
                    }
                    else
                    {
                        AppendRichTextBox($"写入失败，MAC：{leftPack[i].MAC}，SN：{leftPack[i].SN}，BOX_NO：{leftPack[i].BOX_NO}");
                        success = false;
                    }

                    macList += $"'{leftPack[i].MAC}',";
                }

                int execRows = SQLiteMethod.ExecSQL(_sqliteConn, string.Format(updateSQL, macList.TrimEnd(',')));
                AppendRichTextBox($"更新本地数据库成功\r\n更新数量：{execRows}");

                if (success == false)
                {
                    AppendRichTextBox("还有未写入数据库的本地数据，导出失败");
                    return;
                }
            }

#if false
            //将数据导出到EXCEL文件
            //var dataGroup = listPack.GroupBy(a => a.HW_PROVINCE_NAME).ToArray();
            var dataGroup = packs.GroupBy(a => a.DEVICE_TYPE + a.HW_PROVINCE_NAME).Select(g => g.ToList()).ToArray();


            for (int i = 0; i < dataGroup.Length; i++)
            {
                DataTable table = new DataTable()
                {
                    TableName = $"{dataGroup[i][0].DEVICE_TYPE}_{ dataGroup[i][0].HW_PROVINCE_NAME}_{ DateTime.Now.ToString("yyyyMMdd")}"
                };

                DataColumn[] columns = null;

                if (table.TableName.Contains("CMCC")||table.TableName.Contains("GX_926"))
                {
                    columns = new DataColumn[] {
                    new DataColumn("描述"),
                    new DataColumn("ONT类型*"),
                    new DataColumn("设备厂家"),
                    new DataColumn("分公司"),
                    new DataColumn("设备型号"),
                    new DataColumn("箱号"),
                    new DataColumn("S/N"),
                    new DataColumn("MAC"),
                    new DataColumn("终端序列号"),
                    new DataColumn("GPON  SN"),
                    new DataColumn("SSID"),
                    new DataColumn("SSID密码"),
                    new DataColumn("Admin初始/USER密码"),
                    new DataColumn("网关厂家编码"),
                    new DataColumn("硬件版本"),
                    new DataColumn("软/固件版本"),
                    new DataColumn("操作系统类型"),
                    new DataColumn("操作系统版本"),
                    new DataColumn("生产日期"),
                    new DataColumn("发货日期*"),
                };
                }
                else
                {
                    columns = new DataColumn[] {
                    new DataColumn("型号"),
                    new DataColumn("MACAddr"),
                    new DataColumn("DeviceSerialNumber"),
                    new DataColumn("SN"),
                    new DataColumn("FULL_BOX_SN"),
                    new DataColumn("BUILD_TIME") };
                }

                table.Columns.AddRange(columns);
            }
#endif

            List<List<LOCAL_PACKING>> listGroup = new List<List<LOCAL_PACKING>>();
            List<LOCAL_PACKING> list = null;//保存同样类型的pack
            for (int i = 0; i <= packs.Count; i++)
            {
                if (i == 0)
                {
                    list = new List<LOCAL_PACKING>
                    {
                        packs[i]
                    };
                }
                else if (i == packs.Count)//解决最后一个list的问题
                {
                    listGroup.Add(list);
                    list = null;
                }
                else
                {
                    if (packs[i].HW_PROVINCE_NAME == list[0].HW_PROVINCE_NAME
                        && packs[i].DEVICE_TYPE == list[0].DEVICE_TYPE)
                    {
                        list.Add(packs[i]);
                    }
                    else
                    {
                        listGroup.Add(list);
                        list = null;
                        list = new List<LOCAL_PACKING>
                        {
                            packs[i]
                        };
                    }
                }
            }

            AppendRichTextBox($"产品类型总共有[{listGroup.Count}]种");

            for (int i = 0; i < listGroup.Count; i++)
            {
                string deviceType = listGroup[i][0].DEVICE_TYPE.Contains("_")
                    ? listGroup[i][0].DEVICE_TYPE.Substring(0, listGroup[i][0].DEVICE_TYPE.IndexOf("_"))
                    : listGroup[i][0].DEVICE_TYPE;


                DataTable table = new DataTable()
                {
                    TableName = $"{DateTime.Now.ToString("yyyyMMdd")}_{listGroup[i][0].HW_PROVINCE_NAME}_{listGroup[i][0].DEVICE_TYPE}"
                };

                DataColumn[] columns = null;

                if (table.TableName.Contains("CMCC")/* || table.TableName.Contains("GX_926")*/)
                {
                    columns = new DataColumn[] {
                    new DataColumn("描述"),
                    new DataColumn("ONT类型*"),
                    new DataColumn("设备厂家"),
                    new DataColumn("分公司"),
                    new DataColumn("设备型号"),
                    new DataColumn("箱号"),
                    new DataColumn("S/N"),
                    new DataColumn("MAC"),
                    new DataColumn("终端序列号"),
                    new DataColumn("GPON  SN"),
                    new DataColumn("SSID"),
                    new DataColumn("SSID密码"),
                    new DataColumn("Admin初始/USER密码"),
                    new DataColumn("网关厂家编码"),
                    new DataColumn("硬件版本"),
                    new DataColumn("软/固件版本"),
                    new DataColumn("操作系统类型"),
                    new DataColumn("操作系统版本"),
                    new DataColumn("生产日期"),
                    new DataColumn("发货日期*"),
                };

                    table.Columns.AddRange(columns);

                    //写入datatable数据
                    for (int j = 0; j < listGroup[i].Count; j++)
                    {
                        DataRow data = table.NewRow();


                        data[0] = listGroup[i][j].CONTEXT;
                        data[1] = listGroup[i][j].ONT_TYPE;
                        data[2] = listGroup[i][j].FACTORY_NAME;
                        data[3] = listGroup[i][j].BRANCH_NAME;
                        data[4] = deviceType;
                        data[5] = listGroup[i][j].BOX_NO;
                        data[6] = listGroup[i][j].SN;
                        data[7] = listGroup[i][j].MAC;
                        data[8] = listGroup[i][j].XPON_SN;
                        data[9] = listGroup[i][j].XPON_SN;
                        data[10] = listGroup[i][j].SSID;
                        data[11] = listGroup[i][j].SSID_PWD;
                        data[12] = listGroup[i][j].WEB_PWD;
                        data[13] = listGroup[i][j].FACTORY_CODE;
                        data[14] = listGroup[i][j].HW_VERSION;
                        data[15] = listGroup[i][j].SW_VERSION;
                        data[16] = listGroup[i][j].SYSTEM;
                        data[17] = listGroup[i][j].SYSTEM_VERSION;
                        data[18] = listGroup[i][j].PRODUCTION_TIME;
                        data[19] = listGroup[i][j].PACKING_TIME;

                        table.Rows.Add(data);
                    }
                }
                else if(table.TableName.Contains("PT952"))
                {
                    columns = new DataColumn[] {
                    new DataColumn("型号"),
                    new DataColumn("MACAddr"),
                    new DataColumn("DeviceSerialNumber"),
                    new DataColumn("SN"),
                    new DataColumn("FULL_BOX_SN"),
                    new DataColumn("GPON  SN"),
                    new DataColumn("BUILD_TIME") };

                    table.Columns.AddRange(columns);

                    //写入datatable数据
                    //写入datatable数据
                    for (int j = 0; j < listGroup[i].Count; j++)
                    {
                        DataRow data = table.NewRow();

                        data[0] = deviceType;
                        data[1] = listGroup[i][j].MAC;
                        data[2] = listGroup[i][j].DEVICE_SERIAL_NUMBER;
                        data[3] = listGroup[i][j].SN;
                        data[4] = listGroup[i][j].BOX_NO;
                        data[5] = listGroup[i][j].XPON_SN;
                        data[6] = listGroup[i][j].BUILD_TIME;


                        table.Rows.Add(data);
                    }
                }
                else if (table.TableName.Contains("YN_926"))
                {
                    columns = new DataColumn[] {

                    new DataColumn("物料编码"),
                    new DataColumn("产品型号"),
                    new DataColumn("产品设备标识号（S/N）"),
                    new DataColumn("MAC"),
                    new DataColumn("无线名称"),
                    new DataColumn("无线密码") ,
                    new DataColumn("用户密码"),
                    new DataColumn("XPON SN"),
                    new DataColumn("产品序列号"),
                    new DataColumn("箱号"),
                    new DataColumn("栈板号"),
                    new DataColumn("设备型号"),
                    new DataColumn("设备MAC"),
                    new DataColumn("SSID默认名称"),
                    new DataColumn("SSID默认密码"),
                    new DataColumn("管理IP") ,
                    new DataColumn("登录账号"),
                    new DataColumn("密码"),
                    new DataColumn("电压"),
                    new DataColumn("电流"),
                    new DataColumn("设备SN")};

                table.Columns.AddRange(columns);

                    //写入datatable数据
                    //写入datatable数据
                    for (int j = 0; j < listGroup[i].Count; j++)
                    {
                        DataRow data = table.NewRow();

                        data[0] = listGroup[i][j].PRODUCT_CODE;
                        data[1] = _deviceType;
                        data[2] = listGroup[i][j].DEVICE_SERIAL_NUMBER;
                        data[3] = listGroup[i][j].MAC;
                        data[4] = listGroup[i][j].SSID;
                        data[5] = listGroup[i][j].SSID_PWD;
                        data[6] = listGroup[i][j].WEB_PWD;
                        data[7] = listGroup[i][j].XPON_SN;
                        data[8] = listGroup[i][j].SN;
                        data[9] = listGroup[i][j].BOX_NO;
                        data[10] = listGroup[i][j].PACKING_NUM;
                        data[11] = _deviceType;
                        data[12] = listGroup[i][j].MAC;
                        data[13] = listGroup[i][j].SSID;
                        data[14] = listGroup[i][j].SSID_PWD;
                        data[15] = listGroup[i][j].MODEM_IP;
                        data[16] = listGroup[i][j].WEB_USER;
                        data[17] = listGroup[i][j].WEB_PWD;
                        data[18] = "12VDC";
                        data[19] = "1A";
                        data[20] = listGroup[i][j].DEVICE_SERIAL_NUMBER;

                        table.Rows.Add(data);
                    }
                }
                else//YueMe
                {
                    columns = new DataColumn[] {
                    new DataColumn("物料编码"),
                    new DataColumn("产品型号"),
                    new DataColumn("产品设备标识号（S/N）"),
                    new DataColumn("MAC"),
                    new DataColumn("无线名称"),
                    new DataColumn("无线密码") ,
                    new DataColumn("用户密码"),
                    new DataColumn("XPON SN"),
                    new DataColumn("产品序列号"),
                    new DataColumn("箱号"),
                    new DataColumn("栈板号")};

                    table.Columns.AddRange(columns);

                    //写入datatable数据
                    //写入datatable数据
                    for (int j = 0; j < listGroup[i].Count; j++)
                    {
                        DataRow data = table.NewRow();

                        data[0] = listGroup[i][j].PRODUCT_CODE;
                        data[1] = deviceType;
                        data[2] = listGroup[i][j].DEVICE_SERIAL_NUMBER;
                        data[3] = listGroup[i][j].MAC;
                        data[4] = listGroup[i][j].SSID;
                        data[5] = listGroup[i][j].SSID_PWD;
                        data[6] = listGroup[i][j].WEB_PWD;
                        data[7] = listGroup[i][j].XPON_SN;
                        data[8] = listGroup[i][j].SN;
                        data[9] = listGroup[i][j].BOX_NO;
                        data[10] = listGroup[i][j].PACKING_NUM;

                        table.Rows.Add(data);
                    }
                }

                //导出数据到Excel
                //string excelPath = EXCEL_PATH + DateTime.Now.ToString("yyyyMMdd") + "\\";
                string excelFile = EXCEL_PATH + $"{listGroup[i][0].DEVICE_TYPE}_{listGroup[i][0].HW_PROVINCE_NAME}_{listGroup.Count}_{DateTime.Now.ToString("HHmmss")}.xlsx";

                YcdExcelStatic.TableToExcel(table, excelFile);

                AppendRichTextBox($"导出数据到[{excelFile}]成功");
            }

            //backup database drop table LOCAL_PACKING
            string dbFile = $"{ DB_PATH}{DB_FILE}";
            string backupFile = $"{DB_PATH}{DateTime.Now:yyyyMMddHHmmss}.bak";
            File.Copy(dbFile, backupFile, true);

            //删除本地所有数据
            //SQLiteMethod.ExecSQL(_sqliteConn, "DROP TABLE LOCAL_PACKING");
            SQLiteMethod.DeleteDB(DB_PATH + DB_FILE);

            MessageBox.Show("导出数据完成，即将关闭软件！");
            
        }

        private void RunPacking()
        {
            while (_packGroup == false || _queueBoxNo.Count > 0)
            {
                System.Threading.Thread.Sleep(100);

                if (_queueBoxNo.Count == 0) continue;

                string boxNo = _queueBoxNo.Dequeue();

                bool packRet = PackingBoxNo(boxNo);

                if (packRet == false)
                {
                    lock(s_lockObj)
                    _packGroup = true;
                    _queueBoxNo.Clear();
                    _inputBoxNumber = 0;

                    AppendRichTextBox($"打包箱号[{boxNo}]数据失败，即将删除整个栈板数据");
                    SQLiteMethod.ExecSQL(_sqliteConn, $"DELETE FROM LOCAL_PACKING WHERE KEY='{_packSet.KEY}'");
                    AppendRichTextBox("删除栈板数据完成");
                }
            }

            PackingThree();
            SoftShared.SetTextBoxReadOnly(this, this.textBoxEnterBoxNo, false);
            SoftShared.SetControlEnable(this, this.buttonPacking, true);

            lock(s_lockObj)
            _packGroup = false;
            _inputBoxNumber = 0;

            //创建一个新的GUID
            _packSet.KEY = Guid.NewGuid().ToString();

            RunPacking();
        }

#endregion

        private void TextBoxInput_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (this.buttonSaveMessage.Enabled) { MessageBox.Show("请保存配置后扫描"); this.textBoxEnterBoxNo.Clear(); return; }

            if (e.KeyChar == '\r' || e.KeyChar == '\n')
            {
                //扫描箱号标签
                string boxNo = textBoxEnterBoxNo.Text.Trim();

                this.textBoxEnterBoxNo.Clear();

                if (_totalBoxNo.Contains(boxNo))
                {
                    AppendRichTextBox($"ERROR：此箱号[{boxNo}]已扫描");
                    return;
                }

                if (boxNo != null && boxNo.Contains("A") && boxNo.Length == 18)
                {
                    if (_packSet.SCAN_PRODUCT_TOTAL >= _packSet.LIMIT_PRODUCT_TOTAL)
                    {
                        AppendRichTextBox("扫入的产品数量已经达到上限，不能再次扫入");
                        this.textBoxEnterBoxNo.Clear();
                        return;
                    }

                    AppendRichTextBox(string.Format("扫入箱号为[{0}]", boxNo));

                    YCD_ORDER orderW = new YCD_ORDER();

                    //can selected other box sn
                    orderW.SetWhere(
                        $@" ORDER_SN =(
                        select ORDER_SN from Modem.dbo.Device_Data where SN = (
                        select PRO_NO_1 from BOX_MODEM where BOX_NO='{boxNo}'))"
                        );

                    //orderW.SetWhere(string.Format("ORDER_SN=(SELECT TOP 1 ORDER_SN FROM PRODUCT_SN WHERE FULL_BOX_SN='{0}'  AND MONTH=SUBSTRING('{0}',12,1))", boxNo));

                    var selectOrder = MethodWcf.SelectOrderClient(orderW);
                    if (selectOrder.result == false)
                    {
                        AppendRichTextBox("查询箱号对应的订单错误");
                        return;
                    }

                    //判断省份、类型是否相同
                    if (_packSet.HW_PROVINCE_NAME != selectOrder.value[0].PROVINCE || _packSet.DEVICE_TYPE != selectOrder.value[0].DEVICE_TYPE)
                    {
                        AppendRichTextBox(string.Format("当前箱号[{0}]的省份为：[{1}]，类型为：[{2}]，不能装栈板", boxNo, selectOrder.value[0].PROVINCE, selectOrder.value[0].DEVICE_TYPE));
                        return;
                    }

                    //保存箱号
                    if (_totalBoxNo.Contains(boxNo) == false)
                    {

                        lock (_queueBoxNo)
                            _queueBoxNo.Enqueue(boxNo);

                        //_listBoxNo.Add(boxNo);
                        _inputBoxNumber++;
                        _totalBoxNo.Add(boxNo);

                        this.labelInputBox.Text = _inputBoxNumber.ToString();
                        this.labelBoxTotal.Text = _totalBoxNo.Count.ToString();

                    }

                    if (_inputBoxNumber * 20 == _packSet.LIMIT_GROUP)
                    {
                       lock(s_lockObj)
                        _packGroup = true;

                        SoftShared.SetTextBoxReadOnly(this, this.textBoxEnterBoxNo, true);
                        SoftShared.SetControlEnable(this, this.buttonPacking, false);
                    }

                }
                e.Handled = true;
            }

            return;

        }

#if false
        private void PackingSecond()
        {
            if (_listBoxNo.Count == 0) return;

            //使用box_modem来查询数据
            string boxSnSql = " IN('";
            for (int i = 0; i < _listBoxNo.Count; i++)
            {
                boxSnSql += _listBoxNo[i] + "','";
            }
            boxSnSql = boxSnSql.TrimEnd(',', '\'') + "')";

            //查询包装数据，通过箱号寻找所有的DeviceData
            BOX_MODEM boxW = new BOX_MODEM();
            boxW.SetWhere(string.Format("BOX_NO {0} ORDER BY BOX_NO", boxSnSql));

            var selectBoxModem = MethodWcf.SelectBoxModemClient(boxW);

            if (selectBoxModem.result == false) { MessageBox.Show("未能查到包装数据"); return; }

            //写产品数据到本地，按照省份区分，第一种格式的数据
            string dirPath;
            dirPath = DATA_DIR_ONE + DateTime.Now.ToString("yyyyMMdd") + "\\";

            //写打头的标题
            if (File.Exists(dirPath + _fileName) == false)
            {
                string tital = "型号\tMAC\tDeviceSerialNumber\tSN\t箱号\t编译版本\r\n";
                LogHelper.WriteLog(dirPath, _fileName, tital);
            }

            //第二种格式的数据
            string dirPathTwo;
            dirPathTwo = DATA_DIR_TWO + DateTime.Now.ToString("yyyyMMdd") + "\\";

            //写打头的标题
            if (File.Exists(dirPathTwo + _fileNameTwo) == false)
            {
                string tital = "生产日期 \t品牌\t设备型号\t设备MAC\tSSID默认名称\tSSID默认密码\t管理IP\t登陆账号\t密码\t电压\t电流\t设备SN\t生产序列号\r\n";
                LogHelper.WriteLog(dirPathTwo, _fileNameTwo, tital);
            }

            //编译版本查询
            //string version = (from t in _listDeviceType
            //                  where t.DeviceType == _packSet.DEVICE_TYPE && t.PROVINCE == _packSet.HW_PROVINCE_NAME
            //                  select t.BuildTime).FirstOrDefault();
            string version = _deviceType.BuildTime;


            //打印标签使用
            List<PRODUCT_SN> listProSn = new List<PRODUCT_SN>();

            //写入出货
            List<PACKING> listPack = new List<PACKING>();//保存需要写入的出货数据

            string packingMsg = null;//保存本地数据
            string packingMsgTwo = null;//保存本地数据结构2

            //一箱保存一次数据
            for (int i = 0; i < selectBoxModem.value.Count; i++)
            {
                //使用box_modem来查询数据
                var boxModem = selectBoxModem.value[i];


                if (_packSet.SCAN_PRODUCT_TOTAL >= _packSet.LIMIT_PRODUCT_TOTAL)
                {
                    AppendRichTextBox("不能继续扫入产品，产品数量已经达到上限");
                    MessageBox.Show("不能继续扫入产品，产品数量已经达到上限");

                    _listBoxNo.Clear();
                    return;
                }

                //保存需要存储的数据
                List<string> boxMsg = new List<string>();

                string identify = " IN('";

                for (int j = 1; j <= boxModem.COUNT; j++)
                {
                    switch (j)
                    {
                        case 1:
                            identify += boxModem.DSNum_1 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_1, boxModem.PRO_NO_1, boxModem.BOX_NO));
                            break;
                        case 2:
                            identify += boxModem.DSNum_2 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_2, boxModem.PRO_NO_2, boxModem.BOX_NO));
                            break;
                        case 3:
                            identify += boxModem.DSNum_3 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_3, boxModem.PRO_NO_3, boxModem.BOX_NO));
                            break;
                        case 4:
                            identify += boxModem.DSNum_4 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_4, boxModem.PRO_NO_4, boxModem.BOX_NO));
                            break;
                        case 5:
                            identify += boxModem.DSNum_5 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_5, boxModem.PRO_NO_5, boxModem.BOX_NO));
                            break;
                        case 6:
                            identify += boxModem.DSNum_6 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_6, boxModem.PRO_NO_6, boxModem.BOX_NO));
                            break;
                        case 7:
                            identify += boxModem.DSNum_7 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_7, boxModem.PRO_NO_7, boxModem.BOX_NO));
                            break;
                        case 8:
                            identify += boxModem.DSNum_8 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_8, boxModem.PRO_NO_8, boxModem.BOX_NO));
                            break;
                        case 9:
                            identify += boxModem.DSNum_9 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_9, boxModem.PRO_NO_9, boxModem.BOX_NO));
                            break;
                        case 10:
                            identify += boxModem.DSNum_10 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_10, boxModem.PRO_NO_10, boxModem.BOX_NO));
                            break;
                        case 11:
                            identify += boxModem.DSNum_11 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_11, boxModem.PRO_NO_11, boxModem.BOX_NO));
                            break;
                        case 12:
                            identify += boxModem.DSNum_12 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_12, boxModem.PRO_NO_12, boxModem.BOX_NO));
                            break;
                        case 13:
                            identify += boxModem.DSNum_13 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_13, boxModem.PRO_NO_13, boxModem.BOX_NO));
                            break;
                        case 14:
                            identify += boxModem.DSNum_14 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_14, boxModem.PRO_NO_14, boxModem.BOX_NO));
                            break;
                        case 15:
                            identify += boxModem.DSNum_15 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_15, boxModem.PRO_NO_15, boxModem.BOX_NO));
                            break;
                        case 16:
                            identify += boxModem.DSNum_16 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_16, boxModem.PRO_NO_16, boxModem.BOX_NO));
                            break;
                        case 17:
                            identify += boxModem.DSNum_17 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_17, boxModem.PRO_NO_17, boxModem.BOX_NO));
                            break;
                        case 18:
                            identify += boxModem.DSNum_18 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_18, boxModem.PRO_NO_18, boxModem.BOX_NO));
                            break;
                        case 19:
                            identify += boxModem.DSNum_19 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_19, boxModem.PRO_NO_19, boxModem.BOX_NO));
                            break;
                        case 20:
                            identify += boxModem.DSNum_20 + "','";
                            boxMsg.Add(string.Format("\t{0}\t{1}\t{2}\t", boxModem.DSNum_20, boxModem.PRO_NO_20, boxModem.BOX_NO));
                            break;
                        default:
                            break;
                    }
                }

                identify = identify.TrimEnd(',', '\'') + "')";

                //查询IDENTIFY是否在包装数据当中
                PACKING packW = new PACKING();
                packW.SetWhere(string.Format("IDENTIFY {0} ORDER BY ID", identify));
                var selectPacking = MethodWcf.SelectPackingClient(packW);
                if (selectPacking.result)
                {
                    for (int j = 0; j < selectPacking.value.Count; j++)
                    {
                        var packing = selectPacking.value[j];
                        AppendRichTextBox(string.Format("MAC[{0}]已经出货，不能再次扫描，SN[{1}]，BOX_SN[{2}],发货时间[{3}]，栈板编码{4}]", packing.MAC, packing.SN, packing.BOX_NO, packing.PACKING_TIME, packing.PACKING_NUM));
                    }

                    MessageBox.Show("产品已经出货，不能再次扫描");

                    _listBoxNo.Clear();
                    return;
                }

                //查询identify对应的数据
                Device_Data deviceDataW = new Device_Data();
                deviceDataW.SetWhere(string.Format("DeviceSerialNumber {0} ORDER BY SN", identify));

                var selectDeviceData = MethodWcf.SelectDeviceDataClient(deviceDataW);
                if (selectDeviceData.result == false)
                {
                    MessageBox.Show("查询产品信息错误");
                    AppendRichTextBox("查询产品信息错误");
                    return;
                }

                if (boxModem.COUNT != selectDeviceData.value.Count)
                {
                    MessageBox.Show("包装产品数量与查询出的产品数量不一致，BOX：" + boxModem.BOX_NO);
                    AppendRichTextBox("包装产品数量与查询出的产品数量不一致，BOX：" + boxModem.BOX_NO);
                    return;
                }

                //显示总的装栈板数量
                _packSet.SCAN_PRODUCT_TOTAL += boxModem.COUNT;
                //this.labelTotalProduct.Text = this._packSet.LIMIT_TOTAL_PRODUCT.ToString();

                SetControl(labelProductTotal, this._packSet.SCAN_PRODUCT_TOTAL.ToString());

                //生成第一种类型的数据
                int boxNo;

                //是否额外的箱号
                bool isOtherBoxSn = false;
                if (int.TryParse(boxModem.BOX_NO.Substring(13), out boxNo) && boxNo >= 80000)
                {
                    isOtherBoxSn = true;
                }

                for (int k = 0; k < selectDeviceData.value.Count; k++)
                {
                    string msg = boxMsg[k];
                    if (isOtherBoxSn)
                    {
                        msg = (from s in boxMsg
                               where s.Contains(selectDeviceData.value[k].DeviceSerialNumber)
                               select s).FirstOrDefault();
                    }

                    if (msg == null) MessageBox.Show(string.Format("查询箱号数据错误：BOX_NO[{0}],DeviceSerialNumber[{1}]", boxModem.BOX_NO, selectDeviceData.value[k].DeviceSerialNumber));

                    //手动创建PRODUCT_SN
                    if (string.IsNullOrEmpty(selectDeviceData.value[k].SN))
                    {
                        MessageBox.Show(" SN IS EMPTY");

                        AppendRichTextBox(string.Format("SN IS EMPTY,MACADDRESS[{0}]", selectDeviceData.value[k].MACAddr));
                        return;
                    }

                    int snNum;
                    if (int.TryParse(selectDeviceData.value[k].SN.Substring(12), out snNum) == false)
                    {
                        MessageBox.Show("截取sn失败");
                        AppendRichTextBox(string.Format("截取sn失败,MAC[{0}]", selectDeviceData.value[k].MACAddr));
                        return;
                    }

                    listProSn.Add(new PRODUCT_SN() { SN_NUM = snNum, FULL_PRODUCT_SN = selectDeviceData.value[k].SN });

                    //存本地的数据
                    packingMsg += _packSet.DEVICE_TYPE + "\t" + selectDeviceData.value[k].MACAddr + msg + selectDeviceData.value[k].BUILD_TIME + "\r\n";
                    packingMsgTwo += DateTime.Now.Date + "\t"
                        + "友华" + "\t"
                        + _packSet.DEVICE_TYPE + "\t"
                        + selectDeviceData.value[k].MACAddr + "\t"
                        + selectDeviceData.value[k].WIFI_SSID + "\t"
                        + selectDeviceData.value[k].WIFI_Password + "\t"
                        + selectDeviceData.value[k].LanIP + "\t"
                        + selectDeviceData.value[k].WedUser + "\t"
                        + selectDeviceData.value[k].WedPassword + "\t"
                        + "12VDC\t"
                        + "1A\t"
                        + selectDeviceData.value[k].DeviceSerialNumber + "\t"
                        + selectDeviceData.value[k].SN + "\r\n";

                    //存数据库
                    var packU = new PACKING();
                    packU.SetUpdate();

                    packU.MAC = selectDeviceData.value[k].MACAddr;
                    packU.IDENTIFY = selectDeviceData.value[k].DeviceSerialNumber;
                    packU.SN = selectDeviceData.value[k].SN;
                    packU.BOX_NO = boxModem.BOX_NO;
                    packU.PROVINCE = _packSet.HW_PROVINCE_NAME;
                    packU.DEVICE_TYPE = _packSet.DEVICE_TYPE;
                    packU.PACKING_NUM = _packSet.TOTAL_GROUP + "_" + _packSet.SORT_GROUP;
                    packU.BATCH = DateTime.Now.Date.ToString("yyyyMMdd") + _packSet.HW_PROVINCE_NAME + "_" + _packSet.DEVICE_TYPE;
                    packU.PACKING_TIME = DateTime.Now;

                    listPack.Add(packU);//添加到list中

                    //var insertPacking = MethodWcf.InsertPackingClient(packU);
                    //if (insertPacking.result) AppendRichTextBox("写入出货数据成功MAC:"+packU.MAC);
                    //else MessageBox.Show(string.Format("写入包装数据失败，MAC[{0}]，SN[{1}]，BOX_SN[{2}]", packU.MAC, packU.SN, packU.BOX_NO));
                }

                ////写本地日志
                //LogHelper.WriteLog(dirPath, _fileName, packingMsg);
                //LogHelper.WriteLog(dirPathTwo, _fileNameTwo, packingMsgTwo);

            }//大循环

            //写数据库数据和本地数据
            for (int i = 0; i < listPack.Count; i++)
            {
                var insertPacking = MethodWcf.InsertPackingClient(listPack[i]);
                if (insertPacking.result) AppendRichTextBox("写入出货数据成功MAC:" + listPack[i].MAC);
                else MessageBox.Show(string.Format("写入包装数据失败，MAC[{0}]，SN[{1}]，BOX_SN[{2}]", listPack[i].MAC, listPack[i].SN, listPack[i].BOX_NO));
            }


            //写本地日志
            LogHelper.WriteLog(dirPath, _fileName, packingMsg);
            LogHelper.WriteLog(dirPathTwo, _fileNameTwo, packingMsgTwo);

            //保存栈板数据
            string dirPathPack;
            dirPathPack = DATA_DIR_PACK + DateTime.Now.ToString("yyyyMMdd") + "\\";

            //写打头的标题
            if (File.Exists(dirPathPack + _fileNamePack) == false)
            {
                string tital = "日期时间\t省份\t型号\t栈板编号\t产品数量\t开始SN\t结束SN\r\n";
                LogHelper.WriteLog(dirPathPack, _fileNamePack, tital);
            }

            //PRODUCT_SN排序
            listProSn = (from p in listProSn
                         orderby p.SN_NUM
                         select p).ToList();

            if (listProSn[listProSn.Count - 1].SN_NUM - listProSn[0].SN_NUM == listProSn.Count - 1)
            {
                SetControl(labelStartSn, listProSn[0].FULL_PRODUCT_SN);
                SetControl(labelEndSn, listProSn[listProSn.Count - 1].FULL_PRODUCT_SN);

                int packingNum = listProSn.Count;

                string packMsg = DateTime.Now.ToString() + "\t"
                    + _packSet.HW_PROVINCE_NAME + "\t"
                    + _packSet.DEVICE_TYPE + "\t"
                    + _packSet.TOTAL_GROUP + "_" + _packSet.SORT_GROUP + "\t"
                    + packingNum + "\t"
                    + listProSn[0].FULL_PRODUCT_SN + "\t"
                    + listProSn[listProSn.Count - 1].FULL_PRODUCT_SN + "\r\n";

                LogHelper.WriteLog(dirPathPack, _fileNamePack, packMsg);

                LabelPrint(_packSet.SORT_GROUP, _packSet.TOTAL_GROUP, packingNum, listProSn[0].FULL_PRODUCT_SN, listProSn[listProSn.Count - 1].FULL_PRODUCT_SN, _packSet.PACKING_BTW_PATH);
            }
            else
            {
                var list = SplitSnTwo(listProSn);

                for (int i = 0; i < list.Count; i++)
                {
                    SetControl(this.labelStartSn, list[i].StartSn);
                    SetControl(this.labelEndSn, list[i].EndSn);

                    //计算打包数量
                    int packingNum = int.Parse(list[i].EndSn.Substring(12)) - int.Parse(list[i].StartSn.Substring(12)) + 1;

                    string packMsg = DateTime.Now.ToString() + "\t"
                        + _packSet.HW_PROVINCE_NAME + "\t"
                        + _packSet.DEVICE_TYPE + "\t"
                        + _packSet.TOTAL_GROUP + "_" + _packSet.SORT_GROUP + "\t"
                        + packingNum + "\t"
                        + list[i].StartSn + "\t"
                        + list[i].EndSn + "\r\n";

                    LogHelper.WriteLog(dirPathPack, _fileNamePack, packMsg);
                    LabelPrint(_packSet.SORT_GROUP, _packSet.TOTAL_GROUP, packingNum, list[i].StartSn, list[i].EndSn, _packSet.PACKING_BTW_PATH);
                }
            }

            _packSet.SORT_GROUP++;
            //this.textBoxSort.Text = _packSet.SORT.ToString();
            SetControl(textBoxGorupSort, _packSet.SORT_GROUP.ToString());
            AppendRichTextBox("保存数据成功");

            _listBoxNo.Clear();//清空list
        }
#endif
        private void SetControl(Control con, string text, Color col = new Color())
        {
            if (con.InvokeRequired)
            {
                Action<Control, string, Color> d = new Action<Control, string, Color>(SetControl);
                Invoke(d, con, text, col);
            }
            else
            {
                con.ForeColor = col;
                con.Text = text;
            }
        }

        private List<SNStartAndEnd> SplitSnTwo(List<PRODUCT_SN> value)
        {
            if (value == null || value.Count == 0) return null;

            List<SNStartAndEnd> listSplit = new List<SNStartAndEnd>();

            SNStartAndEnd temp = new SNStartAndEnd()
            {
                StartSn = value[0].FULL_PRODUCT_SN,
                EndSn = null
            };

            for (int i = 0; i < value.Count - 1; i++)
            {
                if (value[i + 1].SN_NUM - value[i].SN_NUM != 1)
                {
                    if (temp.StartSn != null)
                    {
                        temp.EndSn = value[i].FULL_PRODUCT_SN;
                        listSplit.Add(temp);
                        temp = new SNStartAndEnd()
                        {
                            StartSn = value[i + 1].FULL_PRODUCT_SN,
                            EndSn = null
                        };
                    }
                    else
                    {
                        temp.EndSn = value[i].FULL_PRODUCT_SN;
                        temp.StartSn = value[i].FULL_PRODUCT_SN;

                        listSplit.Add(temp);
                        temp = new SNStartAndEnd()
                        {
                            StartSn = value[i + 1].FULL_PRODUCT_SN,
                            EndSn = null
                        };
                    }
                }
            }

            if (temp.StartSn != null && temp.EndSn == null)
            {
                temp.EndSn = value[value.Count - 1].FULL_PRODUCT_SN;
                listSplit.Add(temp);
            }

            return listSplit;
        }
        //标签打印
        private void LabelPrint(int sort, int allPacking, int packingNum, string sN1, string sN2, string btwPath)
        {
            if (string.IsNullOrEmpty(btwPath) || File.Exists(btwPath) == false)
            {
                AppendRichTextBox("未能获得打标文件，打印失败！请打开打标软件手动打印！");
                return;
            }

            AppendRichTextBox("开始打印标签……");
            Engine bt = new Engine();

            bt.Start();
            LabelFormatDocument btFormat = bt.Documents.Open(btwPath);
            btFormat.Prompts[_packSet.BTW_SORT_NAME].Value = sort.ToString();
            btFormat.Prompts[_packSet.BTW_GROUP_TOTAL_NAME].Value = allPacking.ToString();
            btFormat.Prompts[_packSet.BTW_PRODUCT_TOTAL_NAME].Value = packingNum.ToString();
            btFormat.Prompts[_packSet.BTW_START_SN_NAME].Value = sN1;
            btFormat.Prompts[_packSet.BTW_END_SN_NAME].Value = sN2;

            btFormat.Print("标签软件");
            btFormat.PrintSetup.Cache.FlushInterval = CacheFlushInterval.PerSession;
            btFormat.Close(SaveOptions.DoNotSaveChanges);
            bt.Stop();

            AppendRichTextBox("标签打印完成");
        }

        private void TextBoxDeviceType_Enter(object sender, EventArgs e)
        {
            //选择产品类型
            DialogDeviceType type = new DialogDeviceType(this.textBoxDeviceType, this.textBoxProvince);
            type.ShowDialog();

            //根据省份获取产品数量
            string productGroupNumber = MethodWcf.ExecuteReturnSQLClient(string.Format(
                "select convert(varchar,MAX(PRODUCT_NUMBER)) from YCD_ORDER where PROVINCE ='{0}' and DEVICE_TYPE='{1}'"
                , this.textBoxProvince.Text, this.textBoxDeviceType.Text));

            this.textBoxProductGroup.Text = productGroupNumber;

            //保存数据到对应的值当中
            int.TryParse(productGroupNumber, out int limitOneNumber);

            _packSet.LIMIT_GROUP = limitOneNumber;
            _packSet.HW_PROVINCE_NAME = this.textBoxProvince.Text;
            _packSet.DEVICE_TYPE = this.textBoxDeviceType.Text;

            //获取deviceType
            Device_Type typeW = new Device_Type();
            typeW.SetWhere();
            typeW.PROVINCE = _packSet.HW_PROVINCE_NAME;
            typeW.DeviceType = _packSet.DEVICE_TYPE;

            var selectType = MethodWcf.SelectDeviceTypeClient(typeW);
            if (selectType.result)
            {
                _deviceType = selectType.value[0];
            }
            else
            {
                MessageBox.Show("未能找到产品的类型信息");
                Close();
            }
        }

        private void ButtonSaveMessage_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(this.textBoxDeviceType.Text)
                || string.IsNullOrEmpty(this.textBoxProvince.Text)
                || string.IsNullOrEmpty(this.textBoxProductGroup.Text)
                || string.IsNullOrEmpty(this.textBoxProductTotal.Text)
                || string.IsNullOrEmpty(this.textBoxGorupSort.Text)
                || string.IsNullOrEmpty(this.textBoxGroupTotal.Text)
                )
            {
                MessageBox.Show("所有数据都不能为空");
                return;
            }

            this.textBoxProductTotal.Enabled = false;
            this.textBoxGroupTotal.Enabled = false;
            this.textBoxProductGroup.Enabled = false;
            this.buttonSaveMessage.Enabled = false;
            this.textBoxDeviceType.Enabled = false;
            this.textBoxProvince.Enabled = false;


            _fileNamePack = string.Format("栈板数据_{0}_{1}_{2}.txt", _packSet.HW_PROVINCE_NAME, _packSet.DEVICE_TYPE, _packSet.LIMIT_PRODUCT_TOTAL);
            _fileName = string.Format("{0}_{1}_{2}.txt", _packSet.HW_PROVINCE_NAME, _packSet.DEVICE_TYPE, _packSet.LIMIT_PRODUCT_TOTAL);
            _fileNameTwo = string.Format("{0}_{1}_{2}.txt", _packSet.HW_PROVINCE_NAME, _packSet.DEVICE_TYPE, _packSet.LIMIT_PRODUCT_TOTAL);

            //获打印标签配置数据
            _packSet.PACKING_BTW_PATH = AppSetting.GetValue(string.Format("{0}_{1}", _packSet.DEVICE_TYPE, _packSet.HW_PROVINCE_NAME));
            if (string.IsNullOrEmpty(_packSet.PACKING_BTW_PATH)) _packSet.PACKING_BTW_PATH = AppSetting.GetValue(string.Format("{0}", _packSet.DEVICE_TYPE));

            if (string.IsNullOrEmpty(_packSet.PACKING_BTW_PATH))
            {
                MessageBox.Show("未配置产品对应的打标模板，请配置完成后再次使用，谢谢！");
                Close();
                return;
            }

            this.textBoxEnterBoxNo.Focus();
        }

        private void ButtonSave_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("一个栈板未满，是否装箱？", "提示", MessageBoxButtons.OKCancel) == DialogResult.OK)
            {
                this.textBoxEnterBoxNo.Focus();

                lock(s_lockObj)
                _packGroup = true;

                //Task.Factory.StartNew(() =>
                //{
                SoftShared.SetTextBoxReadOnly(this, this.textBoxEnterBoxNo, true);
                SoftShared.SetControlEnable(this, this.buttonPacking, false);
                //    //PackingSecond();
                //    PackingThree();
                //    SoftShared.SetTextBoxReadOnly(this, this.textBoxEnterBoxNo, false);
                //    SoftShared.SetControlEnable(this, this.buttonPacking, true);
                //});
            }
        }

        private void FormPacking_Load(object sender, EventArgs e)
        {
            _packSet.SORT_GROUP = 1;
            this.textBoxGorupSort.Text = _packSet.SORT_GROUP.ToString();
            this.textBoxProductGroup.Text = _packSet.LIMIT_GROUP.ToString();

            _packSet.BTW_SORT_NAME = AppSetting.GetValue("SortObject");
            _packSet.BTW_GROUP_TOTAL_NAME = AppSetting.GetValue("AllPackingObject");
            _packSet.BTW_PRODUCT_TOTAL_NAME = AppSetting.GetValue("PackingNumbetObject");
            _packSet.BTW_START_SN_NAME = AppSetting.GetValue("StartSnObject");
            _packSet.BTW_END_SN_NAME = AppSetting.GetValue("EndSnObject");
            _packSet.KEY = Guid.NewGuid().ToString();

            //else { MessageBox.Show("初始化省份信息失败，请检查网络连接"); Dispose(); }
            SQLiteMethod.OnChange += SQLiteMethod_OnChange;

            //创建一个PACKING表
            _sqliteConn = SQLiteMethod.ConnectionSQLite(DB_PATH, DB_FILE);
            string createSQL = @"CREATE TABLE IF NOT EXISTS LOCAL_PACKING (
DEVICE_TYPE VARCHAR(255),
PRODUCT_CODE VARCHAR(255),
HW_PROVINCE_NAME VARCHAR(255),
MAC VARCHAR(255) PRIMARY KEY,
SN VARCHAR(255),
BOX_NO VARCHAR(255),
XPON_SN VARCHAR(255),
SSID VARCHAR(255),
SSID_PWD VARCHAR(255),
MODEM_IP VARCHAR(255),
WEB_USER VARCHAR(255),
WEB_PWD VARCHAR(255),
DEVICE_SERIAL_NUMBER VARCHAR(255),
FACTORY_CODE VARCHAR(255),
HW_VERSION VARCHAR(255),
SW_VERSION VARCHAR(255),
BUILD_TIME VARCHAR(255),
SYSTEM VARCHAR(255),
SYSTEM_VERSION VARCHAR(255),
PRODUCTION_TIME VARCHAR(255),
ONT_TYPE VARCHAR(255),
FACTORY_NAME VARCHAR(255),
BRANCH_NAME VARCHAR(255),
CONTEXT VARCHAR(255),
KEY VARCHAR(255),
PACKING_TIME VARCHAR(255),
PACKING_NUM VARCHAR(255)
)
";
            SQLiteMethod.ExecSQL(_sqliteConn, createSQL);

            //创建索引
            string createIndex = "CREATE INDEX IF NOT EXISTS packing_index ON LOCAL_PACKING(SN,BOX_NO,DEVICE_TYPE,HW_PROVINCE_NAME,KEY)";

            SQLiteMethod.ExecSQL(_sqliteConn, createIndex);

            //循环执行打包事件

            Task.Run(() =>
            {
                RunPacking();
            });

        }

        private void SQLiteMethod_OnChange(string obj)
        {
            //AppendRichTextBox(obj);

            //_packSet.SCAN_PRODUCT_TOTAL += boxModem.COUNT;
            if (obj.Contains("FAIL"))
            {
                AppendRichTextBox(obj);
            }

            _packSet.SCAN_PRODUCT_TOTAL++;

            SoftShared.SetControl(this, this.labelProductTotal, _packSet.SCAN_PRODUCT_TOTAL.ToString());
        }

        //栈板开始号码
        private void TextBoxSort_TextChanged(object sender, EventArgs e)
        {
            int.TryParse(this.textBoxGorupSort.Text, out int sort);
            _packSet.SORT_GROUP = sort;
        }

        //栈板总数
        private void TextBoxTotal_TextChanged(object sender, EventArgs e)
        {
            int.TryParse(this.textBoxGroupTotal.Text, out int total);
            _packSet.TOTAL_GROUP = total;
        }

        //导出数据
        private void ButtonExport_Click(object sender, EventArgs e)
        {
            SoftShared.SetTextBoxReadOnly(this, this.textBoxEnterBoxNo, true);
            SoftShared.SetControlEnable(this, this.buttonPacking, false);
            ExportData();
            SoftShared.SetTextBoxReadOnly(this, this.textBoxEnterBoxNo, false);
            SoftShared.SetControlEnable(this, this.buttonPacking, true);

            Application.Exit();
        }

        //产品出货量限制
        private void TextBoxTotalSend_TextChanged(object sender, EventArgs e)
        {
            int.TryParse(this.textBoxProductTotal.Text, out int totalSend);//发货数量
            _packSet.LIMIT_PRODUCT_TOTAL = totalSend;

            _packSet.TOTAL_GROUP = _packSet.LIMIT_PRODUCT_TOTAL / _packSet.LIMIT_GROUP;
            if (_packSet.LIMIT_PRODUCT_TOTAL % _packSet.LIMIT_GROUP != 0) _packSet.TOTAL_GROUP++;

            this.textBoxGroupTotal.Text = _packSet.TOTAL_GROUP.ToString();
        }

        private void ButtonCancel_Click(object sender, EventArgs e)
        {
            if (_queueBoxNo.Count > 0)
            {
                MessageBox.Show("等待数据处理完成再试");
                return;
            }

            SoftShared.SetTextBoxReadOnly(this, this.textBoxEnterBoxNo, true);
            SoftShared.SetControlEnable(this, this.buttonPacking, false);

            _queueBoxNo.Clear();
            _inputBoxNumber = 0;

            SQLiteMethod.ExecSQL(_sqliteConn, $"DELETE FROM LOCAL_PACKING WHERE KEY='{_packSet.KEY}'");
            AppendRichTextBox("删除栈板数据完成");

            lock (s_lockObj)
                _packGroup = true;
        }

        //栈板产品数量
        private void TextBoxPackingNumber_TextChanged(object sender, EventArgs e)
        {
            int.TryParse(this.textBoxProductGroup.Text.Trim(), out int limitProductGroup);
            _packSet.LIMIT_GROUP = limitProductGroup;
        }

        //写入数据的过程中不能关闭
        private void FormPacking_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this.buttonPacking.Enabled == false)
            {
                MessageBox.Show("写入数据中，不能关闭");
                e.Cancel = true; ;
            }
            else
            {
                SQLiteMethod.ExecSQL(_sqliteConn, $"DELETE FROM LOCAL_PACKING WHERE KEY='{_packSet.KEY}'");
            }
        }
    }
}
